{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "In C:\\Users\\Han\\.conda\\envs\\my_project1\\lib\\site-packages\\matplotlib\\mpl-data\\stylelib\\_classic_test.mplstyle: \n",
      "The text.latex.preview rcparam was deprecated in Matplotlib 3.3 and will be removed two minor releases later.\n",
      "In C:\\Users\\Han\\.conda\\envs\\my_project1\\lib\\site-packages\\matplotlib\\mpl-data\\stylelib\\_classic_test.mplstyle: \n",
      "The mathtext.fallback_to_cm rcparam was deprecated in Matplotlib 3.3 and will be removed two minor releases later.\n",
      "In C:\\Users\\Han\\.conda\\envs\\my_project1\\lib\\site-packages\\matplotlib\\mpl-data\\stylelib\\_classic_test.mplstyle: Support for setting the 'mathtext.fallback_to_cm' rcParam is deprecated since 3.3 and will be removed two minor releases later; use 'mathtext.fallback : 'cm' instead.\n",
      "In C:\\Users\\Han\\.conda\\envs\\my_project1\\lib\\site-packages\\matplotlib\\mpl-data\\stylelib\\_classic_test.mplstyle: \n",
      "The validate_bool_maybe_none function was deprecated in Matplotlib 3.3 and will be removed two minor releases later.\n",
      "In C:\\Users\\Han\\.conda\\envs\\my_project1\\lib\\site-packages\\matplotlib\\mpl-data\\stylelib\\_classic_test.mplstyle: \n",
      "The savefig.jpeg_quality rcparam was deprecated in Matplotlib 3.3 and will be removed two minor releases later.\n",
      "In C:\\Users\\Han\\.conda\\envs\\my_project1\\lib\\site-packages\\matplotlib\\mpl-data\\stylelib\\_classic_test.mplstyle: \n",
      "The keymap.all_axes rcparam was deprecated in Matplotlib 3.3 and will be removed two minor releases later.\n",
      "In C:\\Users\\Han\\.conda\\envs\\my_project1\\lib\\site-packages\\matplotlib\\mpl-data\\stylelib\\_classic_test.mplstyle: \n",
      "The animation.avconv_path rcparam was deprecated in Matplotlib 3.3 and will be removed two minor releases later.\n",
      "In C:\\Users\\Han\\.conda\\envs\\my_project1\\lib\\site-packages\\matplotlib\\mpl-data\\stylelib\\_classic_test.mplstyle: \n",
      "The animation.avconv_args rcparam was deprecated in Matplotlib 3.3 and will be removed two minor releases later.\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import graphviz\n",
    "import lingam\n",
    "from lingam.utils import make_dot\n",
    "import logging\n",
    "import dowhy\n",
    "from dowhy import CausalModel\n",
    "from semopy import Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.read_excel(r\"\\df.xlsx\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Index(['id', 'year', 'region', 'gugun', 'district', 'sex', 'marriage', 'age',\n",
       "       'homeownership', 'education', 'professional', 'income', 'capital',\n",
       "       'religion', 'ideology', 'autonomy', 'social_trust'],\n",
       "      dtype='object')"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.columns.unique()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define the SEM model\n",
    "model_desc = \"\"\"\n",
    "social_trust ~ homeownership + autonomy\n",
    "autonomy ~ sex + marriage + age + religion + ideology + income + education\n",
    "autonomy ~ homeownership\n",
    "social_trust ~ sex + marriage + age + religion + ideology + income + education\n",
    "\"\"\"\n",
    "\n",
    "\n",
    "# Create and fit the model\n",
    "model = Model(model_desc)\n",
    "results = model.fit(df)\n",
    "params = model.inspect()\n",
    "\n",
    "# Function to visualize the SEM model with parameter estimates\n",
    "def visualize_sem_with_params(model, params, path=\"sem_graph\", width=\"80\", height=\"180\", fontsize=\"18\"):\n",
    "    dot = graphviz.Digraph(comment='SEM Model with Parameters')\n",
    "    dot.attr(size=f\"{width},{height}\", ratio='auto')\n",
    "\n",
    "    # List of variables to be shaped as rectangles\n",
    "    rectangle_vars = {'sex', 'marriage' , 'age', 'religion', 'ideology', 'income', 'education', 'homeownership', 'autonomy'}\n",
    "\n",
    "    # Adding nodes with custom shapes\n",
    "    for var in model.vars:\n",
    "        if var in rectangle_vars:\n",
    "            dot.node(var, var, shape='box', color='red' if var == 'homeownership' else 'black', fontcolor='red' if var == 'autonomy' else 'black')\n",
    "        else:\n",
    "            dot.node(var, var, shape='ellipse')  # Default shape as ellipse\n",
    "\n",
    "    # Define custom style for edges and labels\n",
    "    edge_style = {'penwidth': '3.0'}\n",
    "    label_style = {'fontsize': fontsize}\n",
    "\n",
    "    # Adding edges with parameter estimates and p-values\n",
    "    for index, row in params.iterrows():\n",
    "        if row['op'] == '~':\n",
    "            estimate = round(row['Estimate'], 3)\n",
    "            p_value = round(row['p-value'], 3)\n",
    "            significance = '***' if p_value < 0.01 else '**' if p_value < 0.05 else ''\n",
    "            label = f'est: {estimate}, p: {p_value} {significance}'\n",
    "\n",
    "            is_inequality_edge = 'Work_hours' in [row['lval'], row['rval']]\n",
    "            if is_inequality_edge:\n",
    "                edge_style['color'] = 'red'\n",
    "                edge_style['fontcolor'] = 'red'\n",
    "            else:\n",
    "                edge_style['color'] = 'black'\n",
    "                edge_style['fontcolor'] = 'black'\n",
    "\n",
    "            dot.edge(row['rval'], row['lval'], label=label, **edge_style, **label_style)\n",
    "\n",
    "    # Save and render the graph\n",
    "    dot.render(path, view=True)\n",
    "\n",
    "# Visualize the SEM model with specific nodes as rectangles\n",
    "visualize_sem_with_params(model, params, \"sem_example_with_params\", width=\"80\", height=\"180\", fontsize=\"18\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define the SEM model\n",
    "model_desc = \"\"\"\n",
    "social_trust ~ homeownership + autonomy\n",
    "autonomy ~ sex + marriage + age + religion + ideology + income + education\n",
    "autonomy ~ homeownership\n",
    "social_trust ~ sex + marriage + age + religion + ideology + income + education\n",
    "\"\"\"\n",
    "\n",
    "# Create and fit the model\n",
    "model = Model(model_desc)\n",
    "results = model.fit(df)\n",
    "params = model.inspect()\n",
    "\n",
    "# Function to visualize the SEM model with parameter estimates\n",
    "def visualize_focused_sem_with_params(model, params, focus_vars, path=\"focused_sem_graph\", width=\"80\", height=\"100\", fontsize=\"18\"):\n",
    "    dot = graphviz.Digraph(comment='Focused SEM Model with Parameters')\n",
    "    dot.attr(size=f\"{width},{height}\", ratio='auto')\n",
    "\n",
    "    # Define the set of variables to focus on\n",
    "    focus_set = set(focus_vars)\n",
    "\n",
    "    # Adding nodes for the focused variables\n",
    "    for var in focus_set:\n",
    "        dot.node(var, var, shape='ellipse')\n",
    "\n",
    "    # Adding edges with parameter estimates for the focused variables\n",
    "    for index, row in params.iterrows():\n",
    "        if row['op'] == '~' and {row['lval'], row['rval']}.issubset(focus_set):\n",
    "            estimate = round(row['Estimate'], 3)\n",
    "            p_value = round(row['p-value'], 3)\n",
    "            significance = '***' if p_value < 0.01 else '**' if p_value < 0.05 else ''\n",
    "            label = f'est: {estimate}, p: {p_value} {significance}'\n",
    "            dot.edge(row['rval'], row['lval'], label=label, fontsize=fontsize)\n",
    "\n",
    "    # Save and render the graph\n",
    "    dot.render(path, view=True)\n",
    "\n",
    "# Specify the focus variables\n",
    "focus_vars = [\"social_trust\", \"homeownership\", \"autonomy\"]\n",
    "\n",
    "# Visualize the SEM model focused on specified variables\n",
    "visualize_focused_sem_with_params(model, params, focus_vars, \"focused_sem_example\", width=\"80\", height=\"100\", fontsize=\"18\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "            lval  op           rval  Estimate  Std. Err     z-value  \\\n",
      "0       Autonomy   ~            sex  0.051692  0.016176    3.195689   \n",
      "1       Autonomy   ~       marriage  0.356588  0.015269   23.353752   \n",
      "2       Autonomy   ~            age -0.038525  0.006223   -6.190937   \n",
      "3       Autonomy   ~       religion  0.012670  0.016500    0.767853   \n",
      "4       Autonomy   ~       ideology  0.042242  0.004146   10.189692   \n",
      "5       Autonomy   ~       income_1  0.045591  0.004690    9.721761   \n",
      "6       Autonomy   ~      education  0.114296  0.008193   13.950848   \n",
      "7       Autonomy   ~  Homeownership  0.101656  0.018408    5.522443   \n",
      "8   Social_Trust   ~  Homeownership  0.145040  0.011026   13.154860   \n",
      "9   Social_Trust   ~       Autonomy  0.104444  0.003390   30.806478   \n",
      "10  Social_Trust   ~            sex  0.016992  0.009685    1.754394   \n",
      "11  Social_Trust   ~       marriage -0.076255  0.009221   -8.270000   \n",
      "12  Social_Trust   ~            age  0.000149  0.003728    0.039957   \n",
      "13  Social_Trust   ~       religion  0.021999  0.009878    2.226993   \n",
      "14  Social_Trust   ~       ideology  0.006064  0.002486    2.439177   \n",
      "15  Social_Trust   ~       income_1  0.011370  0.002812    4.043845   \n",
      "16  Social_Trust   ~      education  0.001538  0.004920    0.312613   \n",
      "17      Autonomy  ~~       Autonomy  1.687545  0.013515  124.861924   \n",
      "18  Social_Trust  ~~   Social_Trust  0.604818  0.004844  124.861924   \n",
      "\n",
      "         p-value  \n",
      "0   1.394972e-03  \n",
      "1   0.000000e+00  \n",
      "2   5.980769e-10  \n",
      "3   4.425744e-01  \n",
      "4   0.000000e+00  \n",
      "5   0.000000e+00  \n",
      "6   0.000000e+00  \n",
      "7   3.343178e-08  \n",
      "8   0.000000e+00  \n",
      "9   0.000000e+00  \n",
      "10  7.936299e-02  \n",
      "11  2.220446e-16  \n",
      "12  9.681273e-01  \n",
      "13  2.594777e-02  \n",
      "14  1.472074e-02  \n",
      "15  5.258171e-05  \n",
      "16  7.545747e-01  \n",
      "17  0.000000e+00  \n",
      "18  0.000000e+00  \n"
     ]
    }
   ],
   "source": [
    "# Define the SEM model\n",
    "model_desc = \"\"\"\n",
    "social_trust ~ homeownership + autonomy\n",
    "autonomy ~ sex + marriage + age + religion + ideology + income + education\n",
    "autonomy ~ homeownership\n",
    "social_trust ~ sex + marriage + age + religion + ideology + income + education\n",
    "\"\"\"\n",
    "\n",
    "# Create and fit the model\n",
    "model = Model(model_desc)\n",
    "results = model.fit(df)\n",
    "\n",
    "# Inspect the model's results\n",
    "params = model.inspect()\n",
    "\n",
    "# Display the results\n",
    "print(params)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
